package cn.piggy.gateway.core.client;

import cn.piggy.gateway.core.common.CommonUtil;

import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class Request {

    private CountDownLatch latch = new CountDownLatch(1);

    public CountDownLatch getLatch() {
        return latch;
    }

    //每次请求id，id可以设置原子性增长
    private Long id;

    private String path;
    //请求参数
    private Object[] param;
    //响应结果
    private Object result;

    public Object[] getParam() {
        return param;
    }

    public void setParam(Object[] param) {
        this.param = param;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }


    public Request() {
        //当前值新增1并返回结果给id
        this.id = CommonUtil.aid.incrementAndGet();
        //构建请求时，需把请求加进缓存中
        CommonUtil.futures.put(this.getId(), this);
    }

    public Object waitResult (Request request) {
        Long id = request.getId();
        Request requestFuture = CommonUtil.futures.get(id);
        if(requestFuture!=null){
            Object result = requestFuture.getResult();
            while(result==null) {
                try {
                    boolean await = request.getLatch().await(2, TimeUnit.SECONDS);
                    if(await){
                        result = requestFuture.getResult();
                    }else{
                        CommonUtil.futures.remove(id);
                        return "request timeout";
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Request future = CommonUtil.futures.remove(id);
                    if(future!=null){
                        future.getLatch().countDown();
                    }
                    return "exception error";
                }
            }
            return result;
        }
        return "future not exist";
    }

    public void receiveResult (Response resp) {
        Request requestFuture = CommonUtil.futures.remove(resp.getId());
        if(requestFuture!=null) {
            requestFuture.setResult(resp.getResult());
            requestFuture.getLatch().countDown();
        }
    }

    @Override
    public String toString() {
        return "RequestFuture{" +
                "id=" + id +
                ", path='" + path + '\'' +
                ", param=" + Arrays.toString(param) +
                ", result=" + result +
                '}';
    }
}